package com.techventus.ors.craigslist;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;

import com.zenkey.net.prowser.Prowser;
import com.zenkey.net.prowser.Request;
import com.zenkey.net.prowser.Response;
import com.zenkey.net.prowser.Tab;

public class Craig {

	private static boolean debug = true;
	
	private static String namePrefix = "name=\"";
	private static final String hidden_end = "\" value=\"";
	private static final String hidden_second = "<input type=\"hidden\" name=\"";
	private static final String url_end = "\" method=\"post\"";
	private static final String url_ending_caps = "\" method=\"POST";
	private static final String emailPrefFirst = "title=\"your actual email address will appear in the posting\">";
	private static final String detailsPre = "<textarea class=\"req\" tabindex=\"1\" cols=\"80\" style=\"width: 97%\" rows=\"10\" name=\"";
	private static final String ending = "<button type=\"submit\"";
	private static final String quoteEnding = "\"";
	private static final String titlefirst = "<span class=\"req\">Posting Title:</span><br>";
	private static final String specificNamepre = "Specific Location:</span><br><input type=\"text\" class=\"s\" tabindex=\"1\" name=\"";
	private static final String specificNamepost = "\" size=\"20\" maxlength=\"40\"";
	private static final String postingformURLFirst = "<form id=\"postingForm\"  action=\"";
	private static final String alldonefirst = "<div class=\"alldone\">";
	private static final String value_closer = "\" value";
	private static final String click_value_closer = "\" onclick";
	private static final String label_splitter = "</label>";
	private static final String subregionArrayPre = "choose the area nearest you:";
	private static final String subregionArrayPost = "</blockquote>";
	private static final String form_action_tag = "<form action=\"";
	private static final String false_marker = "false;\"";

	private static final String ConfirmEMail = "ConfirmEMail";
	private static final String FromEMail = "FromEMail";

	// TODO MAKE THESE CHOICES
	private static final String EMAIL_PREF_ACTUAL = "P";
	private static final String EMAIL_PREF_GONE = "A";
	private static final String EMAIL_PREF_OBFUSCATED = "C";

	private static final String USER_AGENT = "Mozilla/5.0 (iPad; U; CPU OS 3_2_1 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Mobile/7B405";

	private static final String postingPageIdentifier = "Posting Title:";
	private static final String categoryPageIdentifier = "Please choose a category:";
	private static final String subAreaPageIdentifier = "choose the area nearest you:";
	private static final String imagesUploadIdentifier = "images to be displayed with this posting.";

	private static final String htmlConfirmIdentifier = "Please review and confirm your ad";
	private static final String htmlConfirmIdentifier2 = "HTML look wrong? Check for supported tags and attributes.";

	private static final String startingURLBase = "https://post.craigslist.org/c/%s"
			+ "/C?lang=en";
	
	
	static Prowser p = new Prowser();
	
	private static String confirmPageComplete(String confirmationResponseHTML, Tab tab) throws URISyntaxException {

		String doubleConfirmURL = extract(confirmationResponseHTML,
				form_action_tag, null, quoteEnding);

		String doubleConfirmHidden1NameFirst = doubleConfirmURL;

		String doubleConfirmHidden1Name = extract(confirmationResponseHTML,
				doubleConfirmHidden1NameFirst, hidden_end, quoteEnding);

		String doubleConfirmHidden1Value = extract(
				confirmationResponseHTML, doubleConfirmHidden1Name,
				hidden_end, quoteEnding);

		String doubleConfirmHidden2Name = extract(confirmationResponseHTML,
				doubleConfirmHidden1Value, hidden_end, quoteEnding);
		String doubleConfirmHidden2Value = "y";


		Request doubleConfirmationRequest = new Request(doubleConfirmURL);
		doubleConfirmationRequest.setUserAgent(USER_AGENT);
		doubleConfirmationRequest.setHttpMethod(Request.HTTP_METHOD_POST);
		doubleConfirmationRequest.addParameter(doubleConfirmHidden1Name,
				doubleConfirmHidden1Value);
		doubleConfirmationRequest.addParameter(doubleConfirmHidden2Name,
				doubleConfirmHidden2Value);

		Response doubleConfirmationResponse = tab
				.go(doubleConfirmationRequest);
		String doubleConfirmationResponseHTML = doubleConfirmationResponse
				.getPageSource();
		return doubleConfirmationResponseHTML;
	}


	public static void main(String[] args) {

		p.setDefaultUserAgent(USER_AGENT);
		Tab tab = p.createTab();

		try {
			String startingURL = String.format(startingURLBase, askRegion().getAbrev());
			System.out.println(startingURL);
			
			String initialHTML = fetch(startingURL, USER_AGENT,tab);
			
			System.out.println("*******INITIAL HTML**********");
			Thread.sleep(6400);

			
			
			String subregionalHTML = processPage(tab, initialHTML);

			Thread.sleep(6400);
			/*
			 * Sub-region Choices
			 */

			String subRegionResult = processPage(tab, subregionalHTML);
			
			
			Thread.sleep(6400);
			
			String postPageResult = processPage(tab, subRegionResult);
			
			Thread.sleep(6400);
			
			String imagePageResult = processPage(tab, postPageResult);
			
			Thread.sleep(6400);
			
			String confirmPageResult = processPage(tab, postPageResult);

		} catch (URISyntaxException e) {
			e.printStackTrace();
		} catch (InterruptedException e) {
			e.printStackTrace();
		} catch (ParseException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	private static String askEmailPref() throws IOException{
		System.out.println("1. No Email Displayed");
		System.out.println("2. Actual Email Displayed in Post");
		System.out.println("3. Email Obfuscated/Anonymized");
		String res = "";
		while(res.equals("")){
			String input = getUserInput();
			if(input.equals("1")){
				return Craig.EMAIL_PREF_GONE;
			}else if(input.equals("2")){
				return Craig.EMAIL_PREF_ACTUAL;
			}else if(input.equals("3")){
				return Craig.EMAIL_PREF_OBFUSCATED;
			}
		}
		return res;
	}

	public static String extract(String source, String firstCut,
			String secondCut, String closingString) {
		String temp = source.substring(source.indexOf(firstCut)
				+ firstCut.length());
		if (secondCut != null && !secondCut.equals("")) {
			temp = temp.substring(temp.indexOf(secondCut) + secondCut.length());
		}
		temp = temp.substring(0, temp.indexOf(closingString));
		return temp;
	}

	public static String fetch(String URL, String user_agent, Tab tab)
			throws URISyntaxException {
		Request req = new Request(URL);
		req.setUserAgent(user_agent);
		Response resp = tab.go(req);
		String html = resp.getPageSource();
		return html;
	}

	public static String subAreaPageComplete(String pageSource, Tab tab) throws IOException, URISyntaxException{

		String subregionalSubmissionURL = getSubRegionSubmissionURL(pageSource);

		String hiddenparam2 = pageSource.substring(
				pageSource.indexOf(hidden_second) + 27,
				pageSource.indexOf(ending) - 3);
		String[] split2 = hiddenparam2.split(hidden_end);

		List<String[]> subRegions = getSubRegionChoices(pageSource);
		int subRegionIndex = getSubregionFromUser(subRegions);


		Request req2 = new Request(subregionalSubmissionURL);
		req2.setUserAgent(USER_AGENT);
		req2.setHttpMethod(Request.HTTP_METHOD_POST);
		req2.addParameter(subRegions.get(subRegionIndex - 1)[1],
				String.valueOf(subRegionIndex));
		req2.addParameter(split2[0], split2[1]);
//		System.out.println(req2.toString());
		Response resp2 = tab.go(req2);
		String html2 = resp2.getPageSource();
		return html2;
	}
	
	
	// SELECT RIDESHARING
	public static String categoryPageComplete(String pageSource, Tab tab)
			throws URISyntaxException, ParseException {

		String categorySubmissionURL = pageSource.substring(
				pageSource.indexOf(form_action_tag) + 14,
				pageSource.indexOf(url_ending_caps));
		String hiddenparam = pageSource.substring(
				pageSource.indexOf(hidden_second) + 27,
				pageSource.indexOf(ending) - 3);
		String[] split = hiddenparam.split(hidden_end);
		if (split.length < 2) {
			throw new ParseException("Could Not Parse");
		}

		Request preq = new Request(categorySubmissionURL);
		preq.setUserAgent(USER_AGENT);
		preq.setHttpMethod(Request.HTTP_METHOD_POST);
		preq.addParameter("id", "36");
		preq.addParameter(split[0], split[1]);

		Response presp = tab.go(preq);
		// System.out.println(preq.toString());
		String resultHTML = presp.getPageSource();
		// System.out.println(resultHTML);

		return resultHTML;
	}

	public static String getSubRegionSubmissionURL(String subregionalHTML) {

		String sub2 = subregionalHTML.substring(
				subregionalHTML.indexOf(form_action_tag) + 14,
				subregionalHTML.indexOf(url_ending_caps));
		return sub2;
	}

	public static List<String[]> getSubRegionChoices(String subregionalHTML) {

		List<String[]> subregionList = new ArrayList<String[]>();

		int startIndex = subregionalHTML.indexOf(subregionArrayPre)
				+ subregionArrayPre.length();
		int endIndex = subregionalHTML.indexOf(subregionArrayPost, startIndex);

		String listRawHTML = subregionalHTML.substring(startIndex, endIndex);

		String[] rawsplit = listRawHTML.split(label_splitter);
		for (int i = 0; i < rawsplit.length; i++) {
			int startRegion = rawsplit[i].indexOf(false_marker);
			if (startRegion > 1) {
				String place = rawsplit[i].substring(startRegion + 8);

				int startParamName = rawsplit[i].indexOf(namePrefix) + 6;
				int endParamName = rawsplit[i].indexOf(value_closer);
				if (startParamName > 6) {
					String paramName = rawsplit[i].substring(startParamName,
							endParamName);

					int endValue = rawsplit[i].indexOf(click_value_closer);

					if (endValue > endParamName) {
						String paramValue = rawsplit[i].substring(
								endParamName + 9, endValue);
						String[] list = { place, paramName, paramValue };
						subregionList.add(list);
						System.out.println(place + " " + paramName + " "
								+ paramValue);
					}
				}
			}
		}
		return subregionList;
	}

	public static String getUserInput() throws IOException {
		InputStreamReader converter = new InputStreamReader(System.in);
		BufferedReader in = new BufferedReader(converter);
		String curline = "";
		curline = in.readLine();
		return curline;
	}

	public static int getSubregionFromUser(List<String[]> subRegions)
			throws IOException {
		int val = -1;
		InputStreamReader converter = new InputStreamReader(System.in);
		BufferedReader in = new BufferedReader(converter);
		String curline = "";
		while (!(curline.equals("quit"))) {
			curline = in.readLine();
			try {
				int selection = Integer.parseInt(curline);
				if (selection > 0 && selection <= subRegions.size()) {
					val = selection;
					break;
				} else {
					System.out.println("Compu'er Says No");
				}
			} catch (Exception e) {
				System.out.println("Compu'er Says No");
				System.out.print(">");
			}
		}
		return val;
	}

	public static boolean isPostingPage(String html) {
		if (html.contains(postingPageIdentifier)) {
			return true;
		} else
			return false;
	}

	public static boolean isCategoryPage(String html) {
		if (html.contains(categoryPageIdentifier)) {
			return true;
		} else {
			return false;
		}
	}

	public static boolean isSubAreaPage(String html) {
		if (html.contains(subAreaPageIdentifier)) {
			return true;
		} else {
			return false;
		}
	}

	public static boolean isUploadPage(String html) {
		if (html.contains(imagesUploadIdentifier)) {
			return true;
		} else {
			return false;
		}
	}

	public static boolean isHTMLConfirmPage(String html) {
		if (html.contains(htmlConfirmIdentifier)
				|| html.contains(htmlConfirmIdentifier2)) {
			return true;
		} else {
			return false;
		}
	}
	
	public static Region askRegion() throws IOException {
		Region[] regions = Region.values();

		int i = 0;
		for (Region region : regions) {
			System.out.println((i + 1) + ": " + region);
			i++;
		}
		System.out.println("SELECT YOUR REGION NUMBER: ");
		String res = "";

		int val = -1;
		InputStreamReader converter = new InputStreamReader(System.in);
		BufferedReader in = new BufferedReader(converter);
		String curline = "";
		while (!(curline.equals("quit"))) {
			curline = in.readLine();
			try {
				int selection = Integer.parseInt(curline);
				if (selection > 0 && selection <= regions.length) {
					val = selection;
					break;
				} else {
					System.out.println("Compu'er Says No");
				}
			} catch (Exception e) {
				System.out.println("Compu'er Says No");
				System.out.print(">");
			}
		}

		if (val > 0) {
			return regions[val - 1];
		} else {
			System.exit(0);
			return null;
		}
	}
	
	
	
	
	
	
	
	private static String rideCreationComplete(String html, Tab tab) throws URISyntaxException, IOException{
		String postUrl = extract(html, postingformURLFirst, null, url_end);

		String titleName = extract(html, titlefirst, namePrefix,
				quoteEnding);

		String specificName = html.substring(
				html.indexOf(specificNamepre) + specificNamepre.length(),
				html.indexOf(specificNamepost));
		specificName = specificName.substring(0,
				specificName.indexOf(quoteEnding));

		String emailPrefName = extract(html, emailPrefFirst, namePrefix,
				quoteEnding);

		String hiddenName = extract(html, hidden_second, null, quoteEnding);
		String hiddenValue = extract(html, hidden_second, hidden_end,
				quoteEnding);

		String detailName = extract(html, detailsPre, null, quoteEnding);

		System.out.println(postUrl);
		System.out.println("demailName " + detailName);
		System.out.println("emailPrefName " + emailPrefName);
		System.out.println("hiddenName " + hiddenName + " " + hiddenValue);
		System.out.println("titleName " + titleName);
		System.out.println("Specific Name :" + specificName);
		System.out.println("postURL " + postUrl);

		Request postingRequest = new Request(postUrl);

		postingRequest.setUserAgent(USER_AGENT);
		postingRequest.setHttpMethod(Request.HTTP_METHOD_POST);

		System.out.println("Enter Title for you Rideshare Post");
		String titleValue = getUserInput();
		System.out.println("Enter the Specific Location, eg: Seattle-Portland");
		String specificValue = getUserInput();
		System.out.println("Email Address for Verification");
		String email = getUserInput();
		System.out
				.println("Enter Something actually serious to be your description, yo");
		String detailsValue = getUserInput();

		postingRequest.addParameter(titleName, titleValue);
		postingRequest.addParameter(specificName, specificValue);

		postingRequest.addParameter(FromEMail, email);
		postingRequest.addParameter(ConfirmEMail, email);
		String email_pref = askEmailPref();
		postingRequest.addParameter(emailPrefName, email_pref);
		postingRequest.addParameter(detailName, detailsValue);
		postingRequest.addParameter(hiddenName, hiddenValue);

//		Thread.sleep(6400);

		Response postingResponse = tab.go(postingRequest);
		System.out.println(postingRequest.toString());
		String postResponseHTML = postingResponse.getPageSource();
		System.out.println(postResponseHTML);
		return postResponseHTML;
	}
	
	private static String imagePageComplete(String html, Tab tab) throws URISyntaxException{

		String allDoneUrl = extract(html, alldonefirst,
				form_action_tag, url_end);

		String hidden1First = alldonefirst;

		String hidden1Name = extract(html, hidden1First,
				hidden_second, hidden_end);
		String hidden1ValueFirst = alldonefirst;
		String hidden1Value = extract(html, hidden1ValueFirst,
				hidden_end, quoteEnding);

		String source = html.substring(html
				.indexOf(alldonefirst));

		String hidden2First = hidden1Name;
		String hidden2Second = hidden_second;

		String hidden2Name = extract(source, hidden2First, hidden2Second,
				hidden_end);
		String hidden2Value = "fin";

		Request confirmationRequest = new Request(allDoneUrl);
		confirmationRequest.setUserAgent(USER_AGENT);
		confirmationRequest.setHttpMethod(Request.HTTP_METHOD_POST);
		confirmationRequest.addParameter(hidden1Name, hidden1Value);
		confirmationRequest.addParameter(hidden2Name, hidden2Value);
		confirmationRequest.addParameter(hidden1Name, hidden1Value);

		Response confirmationResponse = tab.go(confirmationRequest);

		System.out.println(confirmationRequest.toString());
		String confirmationResponseHTML = confirmationResponse
				.getPageSource();
		return confirmationResponseHTML;
	}
	
	

	private static String processPage(Tab tab, String html) throws URISyntaxException, ParseException, IOException{
		
		 // Initial Page, Select Ridesharing.
		if(isCategoryPage(html)){
			//
			if(debug)System.out.println("***Category Page*****");
			
			return categoryPageComplete(html, tab);

		}else if(Craig.isSubAreaPage(html)){
			
			if(debug)System.out.println("***Sub Area Page*****");
			
			return subAreaPageComplete(html, tab);
		}else if(Craig.isPostingPage(html)){
			
			if(debug)System.out.println("***Posting Page*****");
			
			return rideCreationComplete(html, tab);
			
		}else if(Craig.isUploadPage(html)){
			
			if(debug)System.out.println("***Upload Page*****");
			
			return imagePageComplete(html, tab);
			
		}else if(Craig.isHTMLConfirmPage(html)){
			
			if(debug)System.out.println("***Confirm Page*****");
			
			return confirmPageComplete(html, tab);
			
		}else{
			return null;
		}
	}
	
	
	
	
	static final String originFromTo = 
			"I am planning a trip from %s to %s on %s.";
	
	static final  String rideSeeking = 
			"I am looking for a ride.";
	
	static final  String riderSeeking = 
			"I have empty seats.";
	
	static final  String contactEmailProvided = 
			"Please email me at %s";
	
	static final String contactURL = 
			"Please book a ride with me at this URL: %s";
	
	static final String contactPhone = 
			"Feel free to call me or SMS me at %s";
	
	static final String passingThrough = 
			"I am likely to be passing through %s.";
			
	
}
